package Chapter3;

public final class MyString implements Comparable<MyString>, java.io.Serializable {
    private final char[] value;

    public MyString() {
        this.value = new char[0];
    }

    public MyString(java.lang.String s) {
        this.value = new char[s.length()];
        for (int i = 0; i < this.value.length; i++)
            this.value[i] = s.charAt(i);
    }

    public MyString(char[] value, int i, int n) {
        if (i >= 0 && n >= 0 && i + n <= value.length) {
            this.value = new char[n];
            for (int j = 0; j < n; j++)
                this.value[j] = value[i + j];
        } else
            throw new StringIndexOutOfBoundsException("i=" + i + ",n=" + n + ",i+n=" + (i + n));
    }

    public MyString(char[] value) {
        this(value, 0, value.length);
    }

    public MyString(MyString s) {
        this(s.value);
    }

    public int length() {
        return this.value.length;
    }

    public java.lang.String toString() {
        return new String(this.value);
    }

    public char charAt(int i) {
        if (i >= 0 && i < this.value.length)
            return this.value[i];
        throw new StringIndexOutOfBoundsException(i);
    }

    public MyString subString(int begin, int end) {
        if (begin == 0 && end == this.value.length)
            return this;
        return new MyString(this.value, begin, end - begin);
    }

    public MyString subString(int begin) {
        return subString(begin, this.value.length);
    }

    public MyString concat(MyString s) {
        if (s == null || s.equals(""))
            s = new MyString(this.value);
        char[] buffer = new char[this.value.length + s.length()];
        int i = 0;
        for (; i < this.value.length; i++)
            buffer[i] = this.value[i];
        for (int j = 0; j < s.value.length; j++)
            buffer[i + j] = s.value[j];
        return new MyString(buffer);
    }

    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj instanceof MyString) {
            MyString str = (MyString) obj;
            if (this.value.length == str.value.length) {
                for (int i = 0; i < this.value.length; i++)
                    if (this.value[i] != str.value[i])
                        return false;
                return true;
            }
        }
        return false;
    }

    @Override
    public int compareTo(MyString s) {
        for (int i = 0; i < this.value.length && i < s.value.length; i++)
            if (this.value[i] != s.value[i])
                return this.value[i] - s.value[i];
        return this.value.length - s.value.length;
    }

    public MyString trim1() {
        MyString str = new MyString("");
        for (int i = 0; i < this.length(); i++)
            if (this.charAt(i) != ' ')
                str = str.concat(this.subString(i, i + 1));
        return str;
    }

    public MyString trim2() {
        char[] buffer = new char[this.value.length];
        int n = 0;
        for (int i = 0; i < this.value.length; i++) {
            if (this.value[i] != ' ')
                buffer[n++] = this.value[i];
        }
        return new MyString(buffer, 0, n);
    }

    /**
     * 返回将s串逆转的串 自编，有待优化和检验
     *
     * @param s
     * @return
     */
    public static String reverse(String s) {
        String str = "";
        for (int length = s.length() - 1; length >= 0; length--) {
            str += "" + s.charAt(length);
        }
        return str;
    }

    /**
     * 比较this与s串的大小，返回两者差值，忽略字母大小写
     *
     * @param str
     * @return
     */
    public int compareToIgnoreCase(MyString str) {
        for (int i = 0; i < this.value.length && i < str.value.length; i++) {
            int c1 = this.value[i], c2 = str.value[i];
            if (c1 >= 'a' && c1 <= 'z')
                c1 -= 'a' - 'A';
            if (c2 >= 'a' && c2 <= 'z')
                c2 -= 'a' - 'A';
            if (c1 != c2)
                return c1 - c2;
        }
        return this.value.length - str.value.length;
    }

    public int indexOf(MyString pattern) {
        return this.indexOf(pattern, 0);
    }

    public int indexOf(MyString pattern, int begin) {
        int n = this.length(), m = pattern.length();
        if (begin < 0)
            begin = 0;
        if (n == 0 || n < m || begin >= n)
            return -1;
        int i = begin, j = 0;
        while (i < n && j < m) {
            if (this.charAt(i) == pattern.charAt(j)) {
                i++;
                j++;
            } else {
                i = i - j + 1;
                j = 0;
                if (i > n - m)
                    break;
            }
        }
        return j == m ? i - m : -1;
    }

    public static StringBuffer replaceAll(StringBuffer target, String pattern, String s) {
        int i = target.indexOf(pattern);
        while (i != -1) {
            target.delete(i, i + pattern.length());
            target.insert(i, s);
            i = target.indexOf(pattern, i + s.length());
        }
        return target;
    }


}
